package top.arryweb.application.common.exception;


import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import top.arryweb.application.common.constant.Result;
import top.arryweb.application.common.constant.StatusCode;

/**
 * @Description 全局异常配置
 * @Author mac
 * @Date 2021/5/29
 **/
@ControllerAdvice
public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler{

  private final Logger logger = LoggerFactory.getLogger(this.getClass());

  @Override
  public void uncaughtException(Thread t, Throwable e) {
    logger.error("未捕获的异常",e);
  }

  @PostConstruct
  public void autoRegister(){
    //设置由于未捕获的异常而导致线程突然终止时调用的默认处理程序
    Thread.setDefaultUncaughtExceptionHandler(this);
  }


  /**
   * 处理空指针的异常
   * @param req
   * @param e
   * @return
   */
  @ExceptionHandler(value =NullPointerException.class)
  @ResponseBody
  public Result<Void> exceptionHandler(HttpServletRequest req, NullPointerException e){
    logger.error("发生空指针异常！原因是:{}{}",req.getMethod(),req.getRequestURI(),e);
    return new Result(false,StatusCode.CODE_BODY_NOT_MATCH,"请求的数据格式不符");
  }

  /**
   * 处理自定义的业务异常
   * @param req
   * @param e
   * @return
   */
  @ExceptionHandler(value = BusinessRuntimeException.class)
  @ResponseBody
  public  Result<Void>  businessExceptionHandler(HttpServletRequest req, BusinessRuntimeException e){
    logger.error("发生业务异常！原因是：",req.getMethod(),req.getRequestURI(),e);
    return new Result(false,StatusCode.CODE_Business_Exception,"发生业务异常",e.getMessage());
  }


  /**
   * 全局异常处理
   * 一般来说代码都是从上到下执行的
   * @param request
   * @param throwable
   * @return
   */
  @ExceptionHandler(Exception.class)
  @ResponseBody
  public Result<String> handleException(HttpServletRequest request,Throwable throwable){
    logger.error("服务器内部错误:{}{}",request.getMethod(), request.getRequestURI(),throwable);
    Result<String> result = new Result<>(false, StatusCode.CODE_Business_Exception,
        "发生业务异常", throwable.getMessage());


    if (throwable instanceof BusinessRuntimeException){
      logger.error("发生业务异常！原因是：{}{}",request.getMethod(),request.getRequestURI(),throwable);
      return result;
    }
    return result.setMessage("服务器内部错误,请联系管理员");
  }
}
/**
 * SpringBoot优雅的全局异常处理 https://www.cnblogs.com/xuwujing/p/10933082.html
 */

